home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / VGX / shadows / pdat.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  9KB  |  270 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.     pdat.c - Support for file read/write of glo_object/PolyData structure.
  19.  
  20.     Tim Heidmann, Silicon Graphics
  21.     June 26, 1991
  22. */
  23. #include <stdio.h>
  24. #include "glo_obj.h"
  25. #include "shadows.h"
  26. #include "vect.h"
  27.  
  28. #define MAXEDGES 10000
  29. #define MAXFACES 10000
  30.  
  31. Boolean
  32. ReadPDataObj(char *filename, glo_ObjPtr *drawlistp, PolyDataPtr *datalistp) {
  33.     /* Try to read a binary drawlist & datalist object file.
  34.        Return TRUE on success. */
  35.     FILE *inf;
  36.     glo_ObjPtr drawlist;
  37.     PolyDataPtr datalist;
  38.     int nList, nTrip, nListBytes, nTripBytes, version;
  39.     int nEdgesBytes, nFacesBytes;
  40.     char buf[20];
  41.  
  42.     /* Open the file for reading and check the file type. */
  43.     if ((inf = fopen(filename, "r")) == NULL ||
  44.         fread(buf, 1, 8, inf) < 8 ||
  45.         strncmp(buf, "pdataobj", 8) != 0) return FALSE;
  46.     if (fread(&version, 1, sizeof(int), inf) < sizeof(int)) return FALSE;
  47.  
  48.     /* Allocate and read drawlist and triplets */
  49.     drawlist = (glo_ObjPtr) malloc(sizeof(glo_ObjTyp));
  50.     if (fread(&nList, 1, sizeof(int), inf) < sizeof(int)) return FALSE;
  51.     nListBytes = nList * sizeof(int);
  52.     drawlist->list = (int *) malloc(nListBytes);
  53.     if (fread(&nTrip, 1, sizeof(int), inf) < sizeof(int)) return FALSE;
  54.     nTripBytes = nTrip * 3 * sizeof(float);
  55.     drawlist->t = (float **) malloc(nTripBytes);
  56.     if (fread(drawlist->list, 1, nListBytes, inf) < nListBytes) return FALSE;
  57.     if (fread(drawlist->t, 1, nTripBytes, inf) < nTripBytes) return FALSE;
  58.  
  59.     /* Allocate and read face and edge lists */
  60.     datalist = (PolyDataPtr) malloc(sizeof(PolyDataRec));
  61.     if (fread(&datalist->nFaces, 1, sizeof(int), inf) < sizeof(int))
  62.     return FALSE;
  63.     nFacesBytes = datalist->nFaces * sizeof(FaceRec);
  64.     datalist->faces = (FacePtr) malloc(nFacesBytes);
  65.     if (fread(&datalist->nEdges, 1, sizeof(int), inf) < sizeof(int))
  66.     return FALSE;
  67.     nEdgesBytes = datalist->nEdges * sizeof(EdgeRec);
  68.     datalist->edges = (EdgePtr) malloc(nEdgesBytes);
  69.  
  70.     if (fread(datalist->faces, 1, nFacesBytes, inf) < nFacesBytes) return FALSE;
  71.     if (fread(datalist->edges, 1, nEdgesBytes, inf) < nEdgesBytes) return FALSE;
  72.  
  73.     if (fclose(inf) != 0) return FALSE;
  74.     *drawlistp = drawlist;
  75.     *datalistp = datalist;
  76.     return TRUE;
  77. }
  78.  
  79.  
  80. Boolean
  81. WritePDataObj(char *filename, glo_ObjPtr drawlist, PolyDataPtr datalist) {
  82.     FILE *outf;
  83.     int version, nTrip, nList;
  84.  
  85.     /* Open the file for writing and write type and version number */
  86.     if ((outf = fopen(filename, "w")) == NULL) return FALSE;
  87.     fwrite("pdataobj", 1, 8, outf);
  88.     version = 1;
  89.     fwrite(&version, 1, sizeof(int), outf);
  90.  
  91.     /* Write the glo_object list and triplets */
  92.     glo_GetLengths(drawlist, &nList, &nTrip);
  93.     fwrite(&nList, 1, sizeof(int), outf);
  94.     fwrite(&nTrip, 1, sizeof(int), outf);
  95.     fwrite(drawlist->list, 1, nList * sizeof(int), outf);
  96.     fwrite(drawlist->t, 1, nTrip * 3 * sizeof(float), outf);
  97.  
  98.     /* Write the pdata face and edge info */
  99.     fwrite(&datalist->nFaces, 1, sizeof(int), outf);
  100.     fwrite(&datalist->nEdges, 1, sizeof(int), outf);
  101.     fwrite(datalist->faces, 1, datalist->nFaces * sizeof(FaceRec), outf);
  102.     fwrite(datalist->edges, 1, datalist->nEdges * sizeof(EdgeRec), outf);
  103.  
  104.     fclose(outf);
  105.     return TRUE;
  106. }
  107.  
  108.  
  109. void
  110. AddEdge(EdgePtr edgeList, int *nEdgesp, int v1, int v2, int thisFace,
  111.     int *iEdgep, int *iSidep)
  112. {
  113.     /* Add an instance of this edge to list.  Set face, and vertices if
  114.        this is the first occurence of this edge. Don't set next recs.
  115.        Return resulting edge index and side in iEdgep, *iSidep. */
  116.     int iEdge, iSide, thisEdge;
  117.  
  118.     for (iEdge = 0; iEdge < *nEdgesp; iEdge++) {
  119.     /* Check for this edge exists already */
  120.     for (iSide=0; iSide<2; iSide++)
  121.         if (edgeList[iEdge].e[iSide].face >= 0 &&
  122.         edgeList[iEdge].e[iSide].vertex == v1 &&
  123.         edgeList[iEdge].e[1-iSide].vertex == v2) {
  124.             *iEdgep = iEdge;
  125.             *iSidep = iSide;
  126.             goto AddNew;
  127.         }
  128.     
  129.     /* Check for this edge in the opposite direction */
  130.     if (edgeList[iEdge].e[0].face >= 0 &&
  131.         edgeList[iEdge].e[0].vertex == v2 &&
  132.         edgeList[iEdge].e[1].vertex == v1) {
  133.         edgeList[iEdge].e[1].face = thisFace;
  134.         *iEdgep = iEdge;
  135.         *iSidep = 1;
  136.         return;
  137.     }
  138.     }
  139.  
  140.     /* Need to add a new edge. */
  141. AddNew:
  142.     edgeList[*nEdgesp].e[0].face = thisFace;
  143.     edgeList[*nEdgesp].e[1].face = -1;
  144.     edgeList[*nEdgesp].e[0].vertex = v1;
  145.     edgeList[*nEdgesp].e[1].vertex = v2;
  146.     *iEdgep = *nEdgesp;
  147.     *iSidep = 0;
  148.     (*nEdgesp)++;
  149. }
  150.  
  151.  
  152. PolyDataPtr
  153. GetPolyData(glo_ObjPtr pdl)
  154. {
  155.     /* Compile a list of all edges - their vertices and adjoining faces.
  156.        Assume no degenerate edges or polygons.
  157.        Rules for edge list data structure:
  158.        - edges go in a counterclockwise direction.
  159.        - face is the polygon on the left side of the edge.
  160.        - this side's vertex is the first vertex, other sides is the second.
  161.        - face element value <0 means that side of the edge unused.
  162.        - nextEdge/nextSide point at next edge reference in this direction
  163.      around the polygon.
  164.     */
  165.     int nEdges, nFaces;
  166.     FaceRec faceList[MAXFACES];
  167.     EdgeRec edgeList[MAXEDGES];
  168.     int i, lastv, firstv, *lip, thisFace, thisEdge, thisSide;
  169.     int lastEdge, lastSide, firstEdge, firstSide;
  170.     PolyDataPtr myPDP;
  171.     Boolean done;
  172.     enum {nonorm, nperv, nperp} mode;
  173.     float edge1[3], edge2[3];
  174.  
  175.     nEdges = 0;
  176.     nFaces = 0;
  177.  
  178.     mode = nonorm;
  179.     lip = pdl->list;
  180.     for (done = FALSE; !done;) {
  181.         switch (*lip) {
  182.     case NONORM: mode = nonorm; break;
  183.     case NPERV: mode = nperv; break;
  184.     case NPERP: mode = nperp; break;
  185.         case ENDLIST: done = TRUE; break;
  186.         case BGNPOLY:
  187.             /* Add a poly face record - first, get the normal */
  188.         lip++;
  189.         thisFace = nFaces++;
  190.         switch(mode) {
  191.         case nonorm:
  192.         /* No normals. Need to compute one */
  193.         vsub(pdl->t[lip[1]], pdl->t[lip[0]], edge1);
  194.         vsub(pdl->t[lip[2]], pdl->t[lip[1]], edge2);
  195.         vcross(edge1, edge2, faceList[thisFace].n);
  196.         vnormal(faceList[thisFace].n);
  197.         break;
  198.         case nperv:
  199.         /* Normal per vertex. Still need to get face normal */
  200.         /* Skip over normals when calculating edge vectors */
  201.         vsub(pdl->t[lip[3]], pdl->t[lip[1]], edge1);
  202.         vsub(pdl->t[lip[5]], pdl->t[lip[3]], edge2);
  203.         vcross(edge1, edge2, faceList[thisFace].n);
  204.         vnormal(faceList[thisFace].n);
  205.         break;
  206.         case nperp:
  207.         /* Normal per polygon; just copy the normal */
  208.         vcopy(pdl->t[lip[0]], faceList[thisFace].n);
  209.         break;
  210.         }
  211.  
  212.             /* then, add each edge of this poly to the master edge list. */
  213.         /* Get the first vertex. */
  214.         lip += (mode == nonorm) ? 0 : 1;
  215.         firstv = *lip;
  216.  
  217.         /* Get the next vertex and add the first edge */
  218.         lip += (mode == nperv) ? 2 : 1;
  219.         AddEdge(edgeList, &nEdges, firstv, *lip, thisFace,
  220.         &firstEdge, &firstSide);
  221.         lastv = *lip;
  222.         lastEdge = firstEdge;
  223.         lastSide = firstSide;
  224.  
  225.         /* While there is another vertex, add an edge to the list */
  226.             while (lip[1] >= 0) {
  227.         /* Get the next vertex, skipping normals */
  228.         lip += (mode == nperv) ? 2 : 1;
  229.  
  230.         /* Add an edge and link the last edge to it */
  231.                 AddEdge(edgeList, &nEdges, lastv, *lip, thisFace,
  232.             &thisEdge, &thisSide);
  233.         edgeList[lastEdge].e[lastSide].nextEdge = thisEdge;
  234.         edgeList[lastEdge].e[lastSide].nextSide = thisSide;
  235.  
  236.                 lastv = *lip;
  237.         lastEdge = thisEdge;
  238.         lastSide = thisSide;
  239.             }
  240.  
  241.         /* Add the final edge to the edge list, link backward & forward */
  242.         AddEdge(edgeList, &nEdges, lastv, firstv, thisFace,
  243.         &thisEdge, &thisSide);
  244.         edgeList[lastEdge].e[lastSide].nextEdge = thisEdge;
  245.         edgeList[lastEdge].e[lastSide].nextSide = thisSide;
  246.         edgeList[thisEdge].e[thisSide].nextEdge = firstEdge;
  247.         edgeList[thisEdge].e[thisSide].nextSide = firstSide;
  248.  
  249.             break;
  250.  
  251.         default: ;
  252.         }
  253.  
  254.     /* Consider the next list item */
  255.     lip++;
  256.     }
  257.  
  258.     /* Allocate and set up a poly data record */
  259.     myPDP = (PolyDataPtr) malloc(sizeof(PolyDataRec));
  260.     myPDP->nEdges = nEdges;
  261.     myPDP->nFaces = nFaces;
  262.     myPDP->faces = (FacePtr) malloc(nFaces * sizeof(FaceRec));
  263.     for (i = 0; i < nFaces; i++) myPDP->faces[i] = faceList[i];
  264.     myPDP->edges = (EdgePtr) malloc(nEdges * sizeof(EdgeRec));
  265.     for (i = 0; i < nEdges; i++) myPDP->edges[i] = edgeList[i];
  266.  
  267.     return myPDP;
  268. }
  269.  
  270.